﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using NCalculator.Operations;

namespace NCalculator
{
    public class Visualization
    {
        #region Attributes
        private StringBuilder _history;
        private StringBuilder _value;
        private TextBox _textBox;
        private TextBox _input;
        private bool _replace;
        private bool _medina;
        private bool _comma;
        #endregion

        public Visualization(TextBox textBox, TextBox input)
        {
            _textBox = textBox;
            _input = input;
            _value = new StringBuilder();
            _history = new StringBuilder();
            _replace = false;
            _medina = false;
            _comma = false;

            // initializing _value
            _value.Append("0");
        }

        #region TextBoxInput
        /// <summary>
        /// Insert new char to InputValue window
        /// </summary>
        /// <param name="value">Character to insert</param>
        public void InsertValue(string value)
        {
            if (_replace)
            {
                _replace = false;
                _value.Clear();
                _input.Text = _value.ToString();
            }

            if (_value.ToString().Equals("0"))
            {
                if (value.Equals("0"))
                    return;

                if (value.Equals(","))
                {
                    if (_comma) return;
                    _value.Append(",");
                    _comma = true;
                    _input.Text = _value.ToString();
                    return;
                }
                else
                {
                    _value.Clear();
                    _value.Append(value);
                    _input.Text = _value.ToString();
                }
            }
            else
            {
                // blocking posibility of second encounter of comma
                if (value.Equals(",") && _comma)
                    return;
                else if (value.Equals(","))
                    _comma = true;

                _value.Append(value);
                _input.Text = _value.ToString();
            }


        }

        /// <summary>
        /// Parse InputValue to double
        /// </summary>
        public double InputValue
        {
            get { return double.Parse(_value.ToString()); }
        }

        /// <summary>
        /// Removing last character from textBoxInputValue
        /// </summary>
        public void RemoveLastChar()
        {
            if (_value.Length > 0)
            {
                _value.Remove(_value.Length - 1, 1);
                _input.Text = _value.ToString();
            }
            if (_value.Length == 0)
                _input.Text = "0";
        }
        
        /// <summary>
        /// Clear textBoxInputValue setting input value to 0
        /// </summary>
        public void ClearInputValue()
        {
            _value.Clear();
            _value.Append("0");
            this._input.Clear();
            _input.Text = "0";
            _comma = false;
        }
        #endregion

        #region History box
        /// <summary>
        /// Adding single ValueNode to history
        /// </summary>
        /// <param name="value">ValueNode</param>
        public void AddValueToHistory(ValueNode node)
        {
            if (node != null)
            {
                _history.Append(node);
                _comma = false;
            }
        }

        /// <summary>
        /// Adding single OperationNode to history
        /// </summary>
        /// <param name="operation">OperationNode</param>
        public void AddOperationToHistory(OperationNode operation)
        {
            if (operation != null)
            {
                _replace = true;
                _history.Append(operation);
                _textBox.Text = _history.ToString();
            }
        }

        #region Median
        /// <summary>
        /// For history purpos, formating median values
        /// </summary>
        /// <param name="value"></param>
        public void MedianInsertValue(string value)
        {
            _replace = true;
            if (!_medina)
            {
                _medina = true;
                _history.Append(value);
                _textBox.Text = _history.ToString();
            }
            else
            {
                _history.Append(" , "+ value);
                _textBox.Text = _history.ToString();
            }
        }

        public void MedianStart()
        {
            _history.Append("Med(");
            _textBox.Text = _history.ToString();
        }
        /// <summary>
        /// Median is finish
        /// </summary>
        public void MedianEnd(string value)
        {
            _medina = false;
            _replace = false;
            _history.Append(") = " + value);
            _textBox.Text = _history.ToString();
        }
        #endregion

        /// <summary>
        /// Special function for example Fibonacci, Median etc
        /// </summary>
        /// <param name="node">Special funcion</param>
        public void AddSepcialFncToHistory(ValueNode node)
        {
            if (node != null)
            {
                _replace = true;
                _history.Append(node);
                _textBox.Text = _history.ToString();
            }
        }

        /// <summary>
        /// Adding result to single line
        /// </summary>
        /// <param name="result">Result of equation</param>
        public void AddResultToHistory(string result)
        {
            _history.Append(" = " + result);
            _history.Append(Environment.NewLine);
            _textBox.Text = _history.ToString();

            // if trying divied by 0
            if (result.Equals(NCalculator.Properties.Resources.DividedByZero))
            {
                _input.Text = "0";
                _replace = true;
                _value.Clear();
                _value.Append("0");
            }
            else
            {
                _input.Text = result;
                _replace = true;
                _value.Clear();
                _value.Append(result);
            }

            // autoscroll to bottom
            _input.SelectionStart = _input.Text.Length;
            _input.ScrollToCaret();
        }
        #endregion

        #region History
        /// <summary>
        /// Set properly formating for history and insert it into textbox
        /// </summary>
        /// <param name="historyCmd">all commands</param>
        /// <param name="result">result of commands</param>
        public void LoadHistory(string historyCmd, string result)
        {
            _history.Append(historyCmd);
            _history.Append(" = " + result);
            _history.Append(Environment.NewLine);
            _textBox.Text = _history.ToString();
        }
        #endregion
    }
}
